#include "HUDManager.h"
#include "../nclgl\Window.h"


HUDManager* HUDManager::pInst = 0;

HUDManager::HUDManager(): Debug_Mode(false),Paused(false),Exit(false),GameTime(1000.0f),Reset_HUD(false),Running(false),Fullscreen(false)
{
	///set screen window to intial position to avoid annoying Hud positioning problems
	RECT rect;
	rect.left = 0;
	rect.top = 0;
	rect.right = 1280;
	rect.bottom = 800;

	ChangeDisplaySettings(0, 0) == DISP_CHANGE_SUCCESSFUL;

	SetWindowLongPtr(Window::GetWindow().GetHandle(), GWL_STYLE, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE);
	AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE);
	MoveWindow(Window::GetWindow().GetHandle(), 0, 0, rect.right-rect.left, rect.bottom-rect.top, TRUE);
}

HUDManager::~HUDManager()
{

	WriteHighScore("High_Score.txt");

	for(vector<Button*>::iterator it = PauseButtons.begin(); it != PauseButtons.end();it++)
	{
		delete (*it);
	}
}

HUDManager* HUDManager::GetInstance()
{
	//If no instance exists create one then return it
	if(pInst == 0)
	{
		pInst = new HUDManager();
	}

	return pInst;
}

void HUDManager::Release()
{
	//if instance exists delete it
	if(pInst)
	{


		delete pInst;
	}
}

void HUDManager::Intialise()
{


	float position = 300;
	/////////////Pause Buttons///////////////////////////////////////
	Button* temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleRunning);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Main_ST.png",TEXTUREDIR"/Button Textures/Main_SE.png");
	PauseButtons.push_back(temp);
	position += 100;

	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleFullscreen);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Full_ST.png",TEXTUREDIR"/Button Textures/Full_SE.png");
	PauseButtons.push_back(temp);
	position += 100;

	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleReset_HUD);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Restart_ST.png",TEXTUREDIR"/Button Textures/Restart_SE.png");
	PauseButtons.push_back(temp);
	position += 100;

	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::TogglePaused);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Resume_ST.png",TEXTUREDIR"/Button Textures/Resume_SE.png");
	PauseButtons.push_back(temp);
	position += 100;

	position = 300;
	/////////////Start Buttons///////////////////////////////////////
	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleExit);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Exit_ST.png",TEXTUREDIR"/Button Textures/Exit_SE.png");
	StartButtons.push_back(temp);
	position += 100;

	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleRunning);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Multi_ST.png",TEXTUREDIR"/Button Textures/Multi_SE.png");
	StartButtons.push_back(temp);
	position += 100;

	temp = new Button(Vector3(1280/2,position,0),40,&HUDManager::ToggleRunning);
	temp->GetSceneNode()->Update(0.0f);
	temp->SetTextures(TEXTUREDIR"/Button Textures/Single_ST.png",TEXTUREDIR"/Button Textures/Single_SE.png");
	StartButtons.push_back(temp);
	position += 100;


	ActiveList = &StartButtons;
	Selected_Button = ActiveList->end()-1;
	(*Selected_Button)->ToggleSelected();

	Health_Bar.SetMesh(Mesh::GenerateQuad());
	Health_Bar.SetColour(Vector4(0,255.0f,0,1));
	Health_Bar.SetModelScale(Vector3(Player_Health*5,10,1));
	Health_Bar.SetTransform(Matrix4::Translation(Vector3(1280/2,800-20,0)));
	Health_Bar.Update(0.0f);
	LoadHighScore("High_Score.txt");

	Logo.SetMesh(Mesh::GenerateQuad());
	Logo.GetMesh()->SetTexture(SOIL_load_OGL_texture(TEXTUREDIR"Logo.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS));
	Logo.SetModelScale(Vector3(400, 100, 1));
	Logo.SetTransform(Matrix4::Translation(Vector3(1280 / 2, 800 - 100, 0)));
	Logo.Update(0.0f);
}

void HUDManager::Update(float msec)
{

	if(Running)
	{

		Health_Bar.SetModelScale(Vector3(Player_Health*5,10,1));
		Health_Bar.SetColour(Vector4(0.0f+(1.0f-(Player_Health/100.0f)*1.0f),((Player_Health/100.0f)*1.0f),0,1));

		if(!Paused)
		{
			GameTime -= (msec/1000.0f);
		}


		if (playerXbox_controller)
		{
			if (playerXbox_controller->GetState().Gamepad.wButtons == XINPUT_GAMEPAD_BACK)
			{
			
				ToggleDebugMode();
			}

			if (playerXbox_controller->GetState().Gamepad.wButtons == XINPUT_GAMEPAD_START)
			{
				TogglePaused();
			}
		}

		if (Window::GetKeyboard()->KeyTriggered(TOGGLE_DEBUG_MODE))
		{
			ToggleDebugMode();
		}

		if (Window::GetKeyboard()->KeyTriggered(TOGGLE_PAUSE_SCREEN))
		{
			TogglePaused();
		}
	}

	if(Paused || !Running)
	{


		if (playerXbox_controller)
		{
			if (Window::GetKeyboard()->KeyTriggered(MENU_UP))
			{

				MoveMenuUp();
			}

			if (Window::GetKeyboard()->KeyTriggered(MENU_DOWN))
			{
				MoveMenuDown();
			}

			if (Window::GetKeyboard()->KeyTriggered(MENU_ENTER))
			{
				(*Selected_Button)->Execute();
			}

		}

		if (playerXbox_controller->GetState().Gamepad.sThumbLY < -6553)
		{
			MoveMenuUp();
		}

		if (playerXbox_controller->GetState().Gamepad.sThumbLY > 6553 )
		{
			MoveMenuDown();
		}

		if (playerXbox_controller->GetState().Gamepad.wButtons == XINPUT_GAMEPAD_A)
		{
			(*Selected_Button)->Execute();
		}
	}

	if (GameTime <= 0 || Player_Health <= 0)
	{
		ToggleReset_HUD();
	}
}

vector<SceneNode*> HUDManager::GetDrawList()
{
	vector<SceneNode*> list;
	
	if(Running)
	{
		list.push_back(&Health_Bar);

		if(Paused)
		{
			for(vector<Button*>::iterator it = PauseButtons.begin(); it != PauseButtons.end(); it++)
			{
				list.push_back((*it)->GetSceneNode());
			}
		}
	}
	else 
	{
		list.push_back(&Logo);

		for(vector<Button*>::iterator it = StartButtons.begin(); it != StartButtons.end(); it++)
		{
			list.push_back((*it)->GetSceneNode());
		}
	}

	return list;
}

void HUDManager::LoadHighScore(char* filename)
{
	ifstream myfile;

	myfile.open(filename,ios::in|ios::binary|ios::ate);

	if(myfile.is_open())
	{
		streampos size = myfile.tellg();
		char* buff = new char[(unsigned int)size];
		myfile.seekg (0, ios::beg);
		myfile.read(buff,size);
		myfile.close();

		int buff_counter = 0;

		for(int i = 0 ; i < 10; i++)
		{
			string storage;
			int score;

			while(buff[buff_counter] != ':' && buff_counter < size)
			{
				buff_counter++;
			}
			buff_counter++;

			while(buff[buff_counter] != 'S' && buff_counter < size)
			{
				storage += buff[buff_counter];
				buff_counter++;
			}

			High_Score[i].Name = storage;
			storage.clear();

			while(buff[buff_counter] != ':' && buff_counter < size)
			{
				buff_counter++;
			}
			buff_counter++;

			while(buff[buff_counter] != '\r' && buff_counter < size)
			{
				storage += buff[buff_counter];
				buff_counter++;
			}

			High_Score[i].Score = atoi(storage.c_str());

		}


	}
}

void HUDManager::WriteHighScore(char* filename)
{
	ofstream outputFile(filename,fstream::out);

	for(int i = 0; i < 10; i++)
	{
		outputFile << "N:" << High_Score[i].Name;
		outputFile << "S:" << High_Score[i].Score << "\r\n";
	}
}


void HUDManager::AddScore(string name ,int score)
{
	HighScorePoints point;

	point.Name = name;
	point.Score = score;

	HighScorePoints storage;

	for(int i = 0; i < 10; i++)
	{
		if(High_Score[i].Score < point.Score)
		{
			storage = High_Score[i];
			High_Score[i] = point;
			point = storage;
		}
	}

}


vector<string> HUDManager::GetHighScoreText()
{
	vector<string> list;

	if(Paused || !Running)
	{

		list.push_back(string("High Scores"));

		for(int i = 0; i < 10; i++)
		{
			string temp;
			temp += to_string(i+1);

			if(i < 9)
			{
				temp += " ";
			}
			temp += ":";  
			temp += High_Score[i].Name;
			temp += " ";
			temp +=  to_string(High_Score[i].Score);
			list.push_back(temp);
		}
	}

	return list;
}

void HUDManager::Reset()
{
	if(Running)
	{
		(*Selected_Button)->ToggleSelected();
		ActiveList = &PauseButtons;
		Selected_Button = ActiveList->end()-1;
		(*Selected_Button)->ToggleSelected();
	}
	else
	{
		(*Selected_Button)->ToggleSelected();
		ActiveList = &StartButtons;
		Selected_Button = ActiveList->end()-1;
		(*Selected_Button)->ToggleSelected();
	}

	Debug_Mode = false;
	Paused = false;
	Exit = false;
	GameTime = 1000.0f;
	Reset_HUD = false;
}

void HUDManager::MoveMenuUp()
{
	if (Selected_Button != ActiveList->end() - 1)
	{
		(*Selected_Button)->ToggleSelected();
		Selected_Button++;
		(*Selected_Button)->ToggleSelected();
	}
	else
	{
		(*Selected_Button)->ToggleSelected();
		Selected_Button = ActiveList->begin();
		(*Selected_Button)->ToggleSelected();
	}
}

void HUDManager::MoveMenuDown()
{
	if (Selected_Button != ActiveList->begin())
	{
		(*Selected_Button)->ToggleSelected();
		Selected_Button--;
		(*Selected_Button)->ToggleSelected();
	}
	else
	{
		(*Selected_Button)->ToggleSelected();
		Selected_Button = ActiveList->end() - 1;
		(*Selected_Button)->ToggleSelected();
	}
}